//
// comm_standard.h
// xmlint
// An XML-based interface for the Protea Project / comm_standard.h defines communications standards
// Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.
// Copyright (C) 2008 Bruce A. James
//
// This program is part of the Protea Project.
//
// The Protea Project is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation, either version 3 of the License, or (at your 
// option) any later version.
//
// The Protea Project is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
// 
// You should have received a copy of the GNU General Public License along 
// with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// Please send correspondence to:
// 
// theproteaproject@gmail.com
//

#ifndef __PROTEA_COMM_STANDARD_H__
#define __PROTEA_COMM_STANDARD_H__

// Xerces includes
#include <xercesc/dom/DOM.hpp>

// Protea includes
#include "../OSDep/utf8.h"

#define MAX_LEN 65535

// Transaction Communication Standard
//////////////////////////////////////////////////////////////////////////////
extern const char lt[];
extern const char sl[];
extern const char gt[];

extern const char xmltag[];
extern const char includestag[];
extern const char	includetag[];
extern const char proteatag[];
extern const char	versiontag[];
extern const char errortag[];
extern const char	transactionlisttag[];
extern const char		applnumbertag[];
extern const char		typetag[];
extern const char		usernametag[];
extern const char		passwordtag[];
extern const char		languagetag[];
extern const char		sessiontag[];

extern const char		transactiontag[];
extern const char			numbertag[];
extern const char			idtag[];
extern const char			nametag[];
extern const char			successtag[];
extern const char			descriptiontag[];
extern const char			testidtag[];
//extern const char			usernametag[];
//extern const char			passwordtag[];
extern const char			ignoretag[];
extern const char			supertag[];
extern const char			actiontag[];
extern const char			phasetag[];
//extern const char			languagetag[];
extern const char			leveltag[];
extern const char			bufferlisttag[];
extern const char				buffertag[];
//extern const char					numbertag[];
//extern const char					nametag[];
//extern const char					typetag[];
extern const char					requiredtag[];
extern const char					ordertag[];
extern const char					fieldtag[];
//extern const char						numbertag[];
//extern const char						nametag[];
extern const char			messagelisttag[];
extern const char				messagetag[];
//extern const char					numbertag[];
extern const char					severitytag[];
//extern const char					requiredtag[];
//extern const char					fieldtag[];
//extern const char					ordertag[];

extern const char	querytransactiontag[];
//extern const char		applnumbertag[];
//extern const char		usernametag[];
//extern const char		passwordtag[];
extern const char		counttag[];
extern const char		starttag[];
extern const char		distincttag[];

//extern const char		buffertag[];
//extern const char			numbertag[];
//extern const char			nametag[];
extern const char				fieldlisttag[];
//extern const char					fieldtag[];
//extern const char						numbertag[];
//extern const char						nametag[];

extern const char			orderlisttag[];
//extern const char				ordertag[];
//extern const char				numbertag[];
//extern const char				nametag[];
extern const char				comparetag[];
extern const char				valuetag[];

extern const char			wherelisttag[];
extern const char					wheretag[];
extern const char						pretag[];
//extern const char						numbertag[];
//extern const char						nametag[];
//extern const char						comparetag[];
extern const char						value1tag[];
extern const char						value2tag[];
extern const char						posttag[];
extern const char						logicaltag[];

//////////
//
// XML Parser Exception Handling
//
//////////
class XMLParseException { 
public:
	struct string_holder {
		char* value;
		int count;
	};

	XMLParseException() {
		svalue = NULL;
	};

	XMLParseException( const char* string ) {
		svalue = NULL;
		SetDesc( string );
	};

	XMLParseException( const XMLParseException& ex ) {
		svalue = ex.svalue;
		svalue->count++;
	};

	~XMLParseException() {
		Clear();
	};

	void Clear() {
		if (svalue) {
			svalue->count--;
			if (svalue->count == 0) {
				free( svalue->value );
				delete svalue;
			};
		};
		svalue = NULL;
	};

	void SetDesc( const char* desc ) {
		Clear();
		if (desc) {
			svalue = new string_holder;
			svalue->count = 1;
			svalue->value = strdup( desc );
		};
	};

	const char* GetDescription();
	void OutputError( XCSocketTransport* cursocket );

protected:
	string_holder* svalue;
};

class XMLParseInvalidAttr : public XMLParseException {
public:
	XMLParseInvalidAttr( XERCES_CPP_NAMESPACE::DOMNode* node, char* parent ) {
		char temp[ 255 ];
		UniTranslator pname( node->getNodeName() );

		sprintf( temp, "Invalid attribute '%s' on node '%s'", pname.UTF8(), parent );
		SetDesc( temp );
	};

	XMLParseInvalidAttr( const char* name, char* parent ) {
		char temp[ 255 ];
		sprintf( temp, "Invalid attribute '%s' on node '%s'", name, parent );
		SetDesc( temp );
	};
};

class XMLParseInvalidAttrValue : public XMLParseException {
public:
	XMLParseInvalidAttrValue( XERCES_CPP_NAMESPACE::DOMNode* node, const char* parent, const char* value ) {
		char temp[ 255 ];
		UniTranslator pname( node->getNodeName() );

		sprintf( temp, "Invalid attribute value '%s' on node '%s'. attribute '%s'", value, parent, pname.UTF8() );
		SetDesc( temp );
	};

	XMLParseInvalidAttrValue( const char* name, const char* parent, const char* value ) {
		char temp[ 255 ];
		sprintf( temp, "Invalid attribute value '%s' on node '%s', attribute '%s'", value, parent, name );
		SetDesc( temp );
	};
};


class XMLParseInvalidTag : public XMLParseException {
public:
	XMLParseInvalidTag( XERCES_CPP_NAMESPACE::DOMNode* node ) {
		char temp[ 255 ];
		UniTranslator pname( node->getNodeName() );

		sprintf( temp, "Invalid tag: '%s'", pname.UTF8() );
		SetDesc( temp );
	};
};

class XMLParseMissingTag : public XMLParseException {
public:
	XMLParseMissingTag( char* tag ) {
		char temp[ 255 ];
		sprintf( temp, "Missing tag '%s'", tag );
		SetDesc( temp );
	};
};

class XMLParseMissingAttr : public XMLParseException {
public:
	XMLParseMissingAttr( char* attr, char* tag ) {
		char temp[ 255 ];
		sprintf( temp, "Missing attribute '%s' in tag '%s'", attr, tag );
		SetDesc( temp );
	};
};





struct XCDefaultType {
	char user[ 255 ];
	char pass[ 255 ];
	char type[ 255 ];
	long lang;
	long app_nbr;
	int session;
};
extern XCDefaultType* curdefaults;




// Function prototypes
void xprintf( bool last, XCSocketTransport *newsocket, const char *lpszFormat, ... );
void xprintstr( bool last, XCSocketTransport *newsocket, const char* string, int nBuf=0 );
void XMLTraceIn( const char* text, ofstream* log = NULL );
void XMLTraceOut( const char* text, ofstream* log = NULL );


#endif
